package com.columboid.web.servlets;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.security.NoSuchAlgorithmException;

import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.bind.JAXBException;

import org.xml.sax.SAXException;

import com.columboid.protocol.syncml.ClientCredential;
import com.columboid.protocol.syncml.ServerAuthentication;
import com.columboid.protocol.syncml.helper.JaxbHelper;
import com.columboid.protocol.syncml.representation.ObjectFactory;
import com.columboid.protocol.syncml.representation.SyncML;
import com.columboid.web.helper.DataStorage;
import com.columboid.web.helper.RequestHelper;
import com.columboid.web.resource.Response;

public final class RoutingServlet extends HttpServlet {
	/**
	 * 
	 */
	private static final long serialVersionUID = -3108563406559619201L;

	public RoutingServlet() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		response.getWriter().write("Welcome to the routing service!<br />Version Nov 23, 2009");
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		ServletInputStream stream = request.getInputStream();
		String content = convertStreamToString(stream);

		String returnString = "";
		try {
			returnString = getServerResponse(content);
			response.setContentType("text/xml");
			response.getWriter().write(returnString);
		} catch (NoSuchAlgorithmException e) {
			response.getWriter().write(e.getMessage());
		} catch (JAXBException e) {
			response.getWriter().write(e.getMessage());
		} 
		catch (SAXException e) {
			response.getWriter().write(e.getMessage());
		}
		catch (Exception e) {
			response.getWriter().write(e.getMessage());
		}
		finally
		{
			stream.close();
		}
		
	}

	private String getServerResponse(String content) throws Exception {
		String xsd = JaxbHelper.getSyncMLSchema();

		StringReader xmlReader = new StringReader(content);
		StringReader xsdReader = new StringReader(xsd);

		String returnString = "";

		SyncML requestSml;

		try {
			requestSml = JaxbHelper.CreateSyncMLObject(xmlReader, xsdReader,SyncML.class,ObjectFactory.class);

			String serverResponse;
			
				serverResponse = RequestHelper.getStringFromSyncMLObject(requestSml);
			 

			returnString = serverResponse;
		} catch (JAXBException e) {
			throw new JAXBException(e);
		} catch (SAXException e) {
			throw new SAXException(e);
		} catch (NoSuchAlgorithmException e) {
			throw new NoSuchAlgorithmException(e);
		} catch (Exception e) {
			throw new Exception(e);
		}
		finally {
			xmlReader.close();
			xsdReader.close();
		}
		return returnString;
	}

	

	private String convertStreamToString(InputStream is) throws IOException {
		/*
		 * To convert the InputStream to String we use the
		 * BufferedReader.readLine() method. We iterate until the BufferedReader
		 * return null which means there's no more data to read. Each line will
		 * appended to a StringBuilder and returned as String.
		 */
		BufferedReader reader = new BufferedReader(new InputStreamReader(is));
		StringBuilder sb = new StringBuilder();

		String line = null;
		try {
			while ((line = reader.readLine()) != null) {
				sb.append(line + "\n");
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			reader.close();
			try {
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		
		return sb.toString();
	}

}
